﻿#region Dont Look This

// /*************************************************************************************
//
// * 文件名称：  Form1.cs
//
// * 作       者：  jieaido@outlook.com
//
// * 创建日期：  2020/04/02/20:34
//
// * 修改日期:     2020/04/06/20:34
//
// * 功能描述：
//
//
//
//                               Copyright (c) Jieaido. AllRights Reserved
//
// *************************************************************************************/

#endregion Dont Look This

using HelpLibrary;
using HelpLibrary.Excel;
using HelpLibrary.MyConfig;
using HelpLibrary.OPC;
using HelpLibrary.OPCHelper;
using HelpLibrary.SQlite;
using OPCAutomation;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Drawing;
using System.Linq;
using System.ServiceProcess;
using System.Threading;
using System.Windows.Forms;
using static HelpLibrary.MyLog.MyLogHelper;

namespace OPC_Rslinx_Jie
{
    public partial class Form1 : Form
    {
        // ReSharper disable once InconsistentNaming
        private readonly MyOPCHelper OPCHelper = MyOPCHelper.Instance;

        public OPCServerState LinkState;
        private readonly MyConfig myConfig = new MyConfig();
        private OPCBrowser oPCBrowser;
        private readonly string serviceFilePath = $"{Application.StartupPath}\\RSServer.exe";
        private readonly string serviceName = "Service1";

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            ThreadPool.RegisterWaitForSingleObject(new AutoResetEvent(true), TryStartRServer3, null, 3000, false);

            CfgTagListReset();
            InitBanci();

            var result = OPCHelper.GetServerList();
            if (result != null)
            {
                foreach (var i in result) Combox_ServerList.Items.Add(i.ToString());

                Combox_ServerList.SelectedIndex = 0;
                cmb_Banci.SelectedIndex = 0;
            }
        }

        private void btn_ServerConnect_Click(object sender, EventArgs e)
        {
            LinkState = MyOPCHelper.Instance.Connect(Combox_ServerList.Text);
            if (LinkState == OPCServerState.OPCRunning) MyOPCHelper.Instance.CreateOPCGroup();
            MessageBox.Show(LinkState.ToString());
        }

        private void btn_additem_Click(object sender, EventArgs e)
        {
            AddItem(textBox_additem.Text.Trim());
            BindDataView();
        }

        #region 服务相关代码

        private void btn_serverStart_Click(object sender, EventArgs e)
        {
            ServiceStart(serviceName);
        }

        private void btn_serverStop_Click(object sender, EventArgs e)
        {
            ServiceStop(serviceName);
        }

        private void btn_serverunit_Click(object sender, EventArgs e)
        {
            UninstallService(serviceFilePath);
        }

        private void btn_serverInit_Click_1(object sender, EventArgs e)
        {
            if (!IsServiceExisted(serviceName))
                InstallService(serviceFilePath);
            else
                MessageBox.Show("服务已经安装!");
        }

        /// <summary>
        /// 判断服务是否存在
        /// </summary>
        /// <param name="serviceName">服务名称</param>
        /// <returns></returns>
        private bool IsServiceExisted(string serviceName)
        {
            var services = ServiceController.GetServices();
            foreach (var sc in services)
                if (sc.ServiceName.ToLower() == serviceName.ToLower())
                    return true;
            return false;
        }

        /// <summary>
        /// 安装服务
        /// </summary>
        /// <param name="serviceFilePath">服务路径</param>
        private void InstallService(string serviceFilePath)
        {
            using (var installer = new AssemblyInstaller())
            {
                installer.UseNewContext = true;
                installer.Path = serviceFilePath;
                IDictionary savedState = new Hashtable();
                installer.Install(savedState);
                installer.Commit(savedState);
            }
        }

        /// <summary>
        /// 卸载服务
        /// </summary>
        /// <param name="serviceFilePath">服务路径</param>

        private void UninstallService(string serviceFilePath)
        {
            using (var installer = new AssemblyInstaller())
            {
                installer.UseNewContext = true;
                installer.Path = serviceFilePath;
                installer.Uninstall(null);
            }
        }

        /// <summary>
        /// 启动服务
        /// </summary>
        /// <param name="serviceName">服务名称</param>

        private void ServiceStart(string serviceName)
        {
            using (var control = new ServiceController(serviceName))
            {
                if (control.Status == ServiceControllerStatus.Stopped) control.Start();
            }
        }

        /// <summary>
        /// 停止服务
        /// </summary>
        /// <param name="serviceName">服务名称</param>
        private void ServiceStop(string serviceName)
        {
            using (var control = new ServiceController(serviceName))
            {
                if (control.Status == ServiceControllerStatus.Running) control.Stop();
            }
        }

        private void TryStartRServer3(object state, bool timedout)
        {
            var ac = new Action(showText);
            Thread.Sleep(2000);
            Invoke(ac); //在同步方法里面实现更新窗体上的数据
        }

        /// <summary>
        /// 用来显示服务器状态
        /// </summary>
        private void showText()
        {
            var serviceControllers = ServiceController.GetServices();
            var server = serviceControllers.FirstOrDefault(service => service.ServiceName == serviceName);
            if (server != null)
                label1.Text = server.Status.ToString();
            else
                label1.Text = "服务未安装";
        }

        #endregion 服务相关代码

        /// <summary>
        /// 将opc数组绑定在dataview
        /// </summary>
        private void BindDataView()
        {
            dataGridView2.DataSource = new BindingList<MyOPCItem>(MyOPCItems.GenerateBindlist());
        }

        /// <summary>
        /// 添加节点到OPC
        /// </summary>
        /// <param name="itemtag"></param>
        private void AddItem(string itemtag)
        {
            try
            {
                MyOPCHelper.Instance.AddItem(itemtag);
            }
            catch (Exception exception)
            {
                MessageBox.Show($"添加节点失败,错误代码{exception.Message}");
                LogHelper.WriteError($"添加节点失败,错误代码{exception.Message}");
            }
        }

        /// <summary>
        /// 展开opc节点,叶子
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_ShowOPCNode_Click(object sender, EventArgs e)
        {
            if (LinkState == OPCServerState.OPCRunning)
            {
                oPCBrowser = MyOPCHelper.Instance.RSserver.CreateBrowser();

                var n1 = NodeTree.Nodes.Add("");
                BuildTreeNodes(oPCBrowser, n1);
                var s = n1.Nodes;
                NodeTree.Nodes.Clear();
                foreach (var item in s) NodeTree.Nodes.Add((TreeNode)item);

                //展开叶子
                //  oPCBrowser.MoveDown(oPCBrowser.Item(1));

                //   oPCBrowser.ShowLeafs(true);
                //  for (int i = 1; i < oPCBrowser.Count; i++)
                //  {
                // NodeTree.Nodes.Add(oPCBrowser.Item(i));
                // MessageBox.Show(oPCBrowser.Item(i));
                //  }
                //foreach (object turn in oPCBrowser)
                //{
                //    NodeTree.Nodes.Add(turn.ToString());
                //}
            }
            else
            {
                MessageBox.Show("请先连接OPC服务器");
            }
        }

        /// <summary>
        /// 获取节点的递归方法
        /// </summary>
        /// <param name="oPCBrowser"></param>
        /// <param name="node"></param>
        private void BuildTreeNodes(OPCBrowser oPCBrowser, TreeNode node)
        {
            oPCBrowser.ShowBranches();
            TreeNode n1 = null;
            foreach (var Branch in oPCBrowser)
            {
                n1 = node.Nodes.Add(Branch.ToString());

                oPCBrowser.MoveDown(Branch.ToString());
                BuildTreeNodes(oPCBrowser, n1);
                //BuildTree(treeNode);
                oPCBrowser.MoveUp();
            }
            //oPCBrowser.ShowLeafs(true);
            //int LeafsCount = oPCBrowser.Count;
            //TreeNode n2;
            //if (n1!=null)
            //{
            //    foreach (string leaf in oPCBrowser)
            //    {
            //        n2 = new TreeNode(oPCBrowser.GetItemID(leaf));
            //        n2.Tag = oPCBrowser.GetItemID(leaf);
            //        n1.Nodes.Add(n2);

            //    }
            //}
        }

        private void NodeTree_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            textBox_additem.Text = e.Node.Text.Trim();
        }

        private void btn_deleteitem_Click(object sender, EventArgs e)
        {
            MyOPCHelper.Instance.RemoveItem(textBox_additem.Text);
            dataGridView2.DataSource = new BindingList<MyOPCItem>(MyOPCItems.GenerateBindlist());
        }

        private void dataGridView2_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (dataGridView2.CurrentRow != null)
            {
                var s = dataGridView2.CurrentRow.Cells[e.ColumnIndex].Value;
                var t = myConfig.UpdateTag(s.ToString(), Combox_ServerList.Text);
                MessageBox.Show($"{t}已添加");
            }

            CfgTagListReset();
        }

        /// <summary>
        /// 清空标签配置列表
        /// </summary>
        private void CfgTagListReset()
        {
            configTagList.Items.Clear();
            configTagList.Items.Add(myConfig.GetTag());
        }

        #region 查询相关
        /// <summary>
        /// 查询主功能
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button5_Click(object sender, EventArgs e)
        {
            var fisrtGrList = DbHelp.SortShift((WorkShift)cmb_Banci.SelectedIndex, Dtp_banci.Value)
                .Where(x => x.CreateTime >= dtp_serachtime1.Value && x.CreateTime <= dtp_serachtime2.Value)
                .Select(x => new MyDisModel(x));
            dataGridView1.CellFormatting +=
                dataGridView1_CellFormatting;

            if (cb_time.Checked)
            {
                var s1 = fisrtGrList.Where(
                    x => x.CreateTime < dtp_fucktime1.Value || x.CreateTime >= dtp_fucktime2.Value);

                var s2 = fisrtGrList
                    .Where(x => x.CreateTime >= dtp_fucktime1.Value && x.CreateTime < dtp_fucktime2.Value)
                    .Select(x => x.ZeroModel());//把在剔除时间中的行清零

                fisrtGrList = s1.Union(s2).ToList();

                var MyStatisticsModels = new List<MyStatisticsModel>();
                MyStatisticsModels.Add(new MyStatisticsModel("甲班"));
                MyStatisticsModels.Add(new MyStatisticsModel("乙班"));
                MyStatisticsModels.Add(new MyStatisticsModel("丙班"));
                MyStatisticsModels.Add(new MyStatisticsModel("丁班"));
                for (var i = 0; i < 4; i++)
                {
                    MyStatisticsModels[i].yeBanCount = s1.Count(x => x.YeBan == (WorkShift)i);
                    MyStatisticsModels[i].baiBanCount = s1.Count(x => x.Baiban == (WorkShift)i);
                    MyStatisticsModels[i].zhongBanCount = s1.Count(x => x.Zhongban == (WorkShift)i);
                    MyStatisticsModels[i].YeBanSum = s1.Where(x => x.YeBan == (WorkShift)i).Sum(x => x.YeBanGr);
                    MyStatisticsModels[i].BaiBanSum = s1.Where(x => x.Baiban == (WorkShift)i).Sum(x => x.BaiBanGr);
                    MyStatisticsModels[i].ZhongBanSum =
                        s1.Where(x => x.Zhongban == (WorkShift)i).Sum(x => x.ZhongBanGr);
                }

                dataGridView3.DataSource = MyStatisticsModels.OrderBy(x => x.GrSum).ToList();
                var celltype = new DataGridViewCellStyle();
                celltype.Format = "f2";
                dataGridView3.Columns[7].DefaultCellStyle = celltype;
            }

            if (cb_banci.Checked)
            {
                var ws = (WorkShift)cb_fuckbanci.SelectedIndex;
                var rr = fisrtGrList.Where(x => x.YeBan == ws).Select(x => new MyDisBanciModel(x, "夜班", x.YeBanGr));

                var rr2 = fisrtGrList.Where(x => x.Baiban == ws).Select(x => new MyDisBanciModel(x, "白班", x.BaiBanGr));

                var rr3 = fisrtGrList.Where(x => x.Zhongban == ws).Select(
                    x => new MyDisBanciModel(x, "中班", x.ZhongBanGr)
                );
                var rr4 = fisrtGrList.Where(x => x.Zhongban != ws && x.YeBan != ws && x.Baiban != ws)
                    .Select(x => new MyDisBanciModel(x, "休息", 0f));
                dataGridView1.DataSource = rr.Union(rr2).Union(rr3).Union(rr4).OrderBy(x => x.CreateTime).ToList();
                return;
            }

            dataGridView1.DataSource = fisrtGrList.OrderBy(x => x.CreateTime).ToList();
        }

        private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            var headerText = dataGridView1.Columns[e.ColumnIndex].HeaderText;

            if (headerText == "班次1" || headerText == "班次2" || headerText == "班次3")
            {
                var stringValue = e.Value.ToString();
                var cell = dataGridView1[e.ColumnIndex - 1, e.RowIndex];
                // if (stringValue == null) return;
                switch (stringValue)
                {
                    case "A":
                        e.Value = "甲班";
                        cell.Style.BackColor = Color.Coral;
                        e.CellStyle.BackColor = Color.Coral;
                        break;

                    case "B":
                        e.Value = "乙班";
                        cell.Style.BackColor = Color.Yellow;
                        e.CellStyle.BackColor = Color.Yellow;
                        break;

                    case "C":
                        e.Value = "丙班";
                        cell.Style.BackColor = Color.GreenYellow;
                        e.CellStyle.BackColor = Color.GreenYellow;
                        break;

                    case "D":
                        e.Value = "丁班";
                        cell.Style.BackColor = Color.CornflowerBlue;
                        e.CellStyle.BackColor = Color.CornflowerBlue;
                        break;
                }
            }
            else if (headerText == "班次")
            {
                var stringValue = e.Value.ToString();
                var cell = dataGridView1[e.ColumnIndex - 1, e.RowIndex];
                switch (stringValue)
                {
                    case "夜班":

                        cell.Style.BackColor = Color.Coral;
                        e.CellStyle.BackColor = Color.Coral;
                        break;

                    case "白班":
                        e.Value = "白班";
                        cell.Style.BackColor = Color.Yellow;
                        e.CellStyle.BackColor = Color.Yellow;
                        break;

                    case "中班":
                        e.Value = "中班";
                        cell.Style.BackColor = Color.GreenYellow;
                        e.CellStyle.BackColor = Color.GreenYellow;
                        break;

                    case "休息":
                        e.Value = "休息";
                        cell.Style.BackColor = Color.DarkGray;
                        e.CellStyle.BackColor = Color.DarkGray;
                        break;
                }
            }
        }

        private void Btn_Statistics_Click(object sender, EventArgs e)
        {
            List<MyDisModel> dt = null;
            List<MyStatisticsModel> dt2 = null;
            try
            {
                dt = (List<MyDisModel>)dataGridView1.DataSource;
                dt2 = (List<MyStatisticsModel>)dataGridView3.DataSource;
            }
            catch (Exception)
            {
                MessageBox.Show("错误,检查表格!");
                return;
            }

            ExcelHelp.ExportToExcel(dt, dt2);
        }

        #endregion 查询相关

        private void button6_Click(object sender, EventArgs e)
        {
            myConfig.SetBanci(Dtp_banci.Value, cmb_Banci.SelectedIndex);
            MessageBox.Show("写入成功!");
            InitBanci();
        }

        /// <summary>
        /// 通过配置初始化班次
        /// </summary>
        private void InitBanci()
        {
            string s;
            Dtp_banci.Text = myConfig.GetBanci(out s);
            cmb_Banci.SelectedIndex = int.Parse(s);
        }

        private void Label12_DoubleClick(object sender, EventArgs e)
        {
            MessageBox.Show("你好!");
        }

        /// <summary>
        /// 生产模拟数据库
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button1_Click_1(object sender, EventArgs e)
        {
            if (DateTime.Now.Second == 15)
            {
                var rn = new Random();

                var t = DateTime.Today.Day;
                var db = new MySQliteContext();
                for (var i = 0; i < 360; i++)
                {
                    var gr = new Gr();
                    gr.a = rn.Next(10, 30);
                    gr.b = rn.Next(10, 30);
                    gr.c = rn.Next(10, 30);
                    gr.d = rn.Next(10, 30);
                    gr.e = rn.Next(10, 30);
                    gr.f = rn.Next(10, 30);
                    gr.CreateTime = DateTime.Today.AddDays(i);

                    db.gr.Add(gr);
                }

                using (db)
                {
                    db.SaveChanges();
                }
            }
        }

        private void NodeTree_AfterSelect(object sender, TreeViewEventArgs e)
        {
            tagTree.Nodes.Clear();
            if (NodeTree.SelectedNode != null)
            {
                var path = NodeTree.SelectedNode.FullPath;
                Array Branches = path.Split('\\');
                try
                {
                    oPCBrowser.MoveTo(ref Branches);
                }
                catch (Exception)
                {
                    return;
                }

                oPCBrowser.ShowLeafs(false);
                foreach (string item in oPCBrowser)
                    // e.Node.Nodes.Add(item.ToString());
                    tagTree.Nodes.Add(oPCBrowser.GetItemID(item));
                //var i= oPCBrowser.GetAccessPaths(item.ToString());
                //  oPCBrowser.ShowLeafs(false);
                oPCBrowser.MoveToRoot();
            }
        }

        private void TagTree_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            textBox_additem.Text = e.Node.Text.Trim();
        }

        private void Label13_DoubleClick(object sender, EventArgs e)
        {
            MessageBox.Show("主要是不想做了.累了");
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            MyOPCHelper.Instance.ReleaseOPC();
        }
    }
}